#include "common.hpp"

static const char *optString = "p:m:h?";

static const struct option longOpts[] = {
	{ "help", no_argument, NULL, 'h' },
	{ "max", required_argument, NULL, 'm'},
	{ "people", required_argument, NULL, 'p'},
	{ 0,0,0,0}
};

int main (int argc, char* const argv[]) {
	// Objetos IPC
	ipc::semaphore_with_exceptions mutex( ftok(BASE_NAME,10),0 );
	ipc::shared_memory_with_exceptions<sGimnasio> gim( ftok(BASE_NAME,11) );

	ipc::messages_queue_with_exceptions cola1 (ftok(BASE_NAME,16) );
	ipc::messages_queue_with_exceptions cola2 (ftok(BASE_NAME,17) );

	// Parametros.
	long maximo = 10;
	long personas = 10;

	// Variables.
	int longIndex = 0;
	int option = 0;
	bool ayuda = false;

	while ( (option = getopt_long(argc,argv,optString,longOpts,&longIndex) ) != EOF ) {
		switch (option) {
			case '?':
			case 'h':
			case ':':
				ayuda = true;
			case 'm':
				maximo = parse(optarg,0);
				break;
			case 'p':
				personas = parse(optarg,0);
				break;
			default:
				break;
		}
	}

	if ( ayuda || (maximo <= 0) || (personas <= 0) ) {
		std::cerr << "Proceso para preparación del entorno y ejecución." << std::endl;
		std::cerr << "\tUso: " << argv[0] << " [-h] <-max natural> <-people natural>" << std::endl;
		std::cerr << "\tParametros:" << std::endl;
		std::cerr << "\t\t-h,--help:\tMostrar este mensaje de ayuda." << std::endl;
		std::cerr << "\t\t-m,--max:\tEspacios disponibles en el gimnasio." << std::endl;
		std::cerr << "\t\t-p,--people:\tCantidad de personas a generar." << std::endl;

		return (ayuda) ? 0 : -1;
	}

	try {

		mutex.get(PERMITS | IPC_CREAT|IPC_EXCL);
		mutex.init(1);

		gim.get(PERMITS | IPC_CREAT|IPC_EXCL);
		(*gim).cantidad = 0;
		(*gim).maximo = maximo;

		cola1.get(PERMITS | IPC_CREAT|IPC_EXCL);
		cola2.get(PERMITS | IPC_CREAT|IPC_EXCL);

		logger << "Lanzador: Inicio. Gimnasio con capacidad para " << maximo << " personas." << nl;

		// Preparo una puerta.
		if (fork() == 0) {
			execlp("./puerta","puerta","-k",c_parse(ftok(BASE_NAME,16)),(char*)NULL);
		}

		// Preparo la otra puerta.
		if (fork() == 0) {
			execlp("./puerta","puerta","-k",c_parse(ftok(BASE_NAME,17)),(char*)NULL);
		}

		// Comienzo a generar personas.
		if (fork() == 0) {
			execlp("./arribos","arribos","-p",c_parse(personas),(char*)NULL);
		}

	} catch (ipc::exception& e) {
		logger << "Lanzador: " << e.what() << nl;
		exit(-1);
	}

	return 0;
}

